package de.hm.edu.chartservice;

import java.math.BigDecimal;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.UUID;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import de.hm.edu.kpi.IObjectFactory;
import de.hm.edu.kpi.KeyIndicator;
import de.hm.edu.kpi.ObjectFactoryImpl;
import de.hm.edu.kpi.PieChart;
import de.hm.edu.kpi.PieValueSeries;

/**
 * A Singleton Class representing the Product Share KPI
 * @author Peter Goldenbogen (Munich University of Applied Science)
 *
 */
public class ProductShare {

		/**ProductShare Singleton Instance*/
	    private static ProductShare instance = null;
	    /**A nested key Indicator object*/
	    private static KeyIndicator productShare;
	    /**key Indicator title*/
	    private static String title = "Product Share Pie Graph";
	    /**key Indicator description*/
	    private static String description = "A pie graph representing the relative amount of products sold within the given timeframe";
	 
	    private ProductShare() {}
	    
		/**
		 * Initializes the KPI object parameters  and data
		 * @return a SalesVolume singleton instance
		 */
	    public static ProductShare getInstance() {
	    	
	    	if (instance == null){
	    		
		    	instance = new ProductShare();
		    	IObjectFactory oFactory = new ObjectFactoryImpl();
	
		    	// Init ProductShare Object
		    	productShare = oFactory.createKeyIndicator();
		    	productShare.setTitle(title);
		    	productShare.setDescription(description);
		    	productShare.setIdentifier(UUID.randomUUID().toString());
		    	productShare.setCreationTime(getXMLGregTimestamp());
		    	productShare.setDataPeriodStart(getXMLGregTimestamp());
		    	//Create pie chart and assign it to key indicator
		    	PieChart pie = oFactory.createPieChart();
		    	productShare.setPieChartOrLineChart(pie);
	    	}
	    	
	        return instance;
	    }
	    
		/**
		 * Updates the KPI data
		 * @param amount The amount that will be added to a product volume
		 * @param product The product where the amount will be added
		 */
		public void update(String product, int amount) {
			//Update Product Share Chart
			IObjectFactory oFactory = new ObjectFactoryImpl();
			PieValueSeries pvs = oFactory.createPieValueSeries();
			pvs.setTitle(product);
			pvs.setValue(new BigDecimal(amount));
			
			PieChart pie =  (PieChart) getInstance().getProductShare().getPieChartOrLineChart();
			
			boolean newProduct = true;
			
			for(PieValueSeries currentPvs : pie.getPieValueSeries()){
				if(currentPvs.getTitle().equals(pvs.getTitle())){
					//get equal CategorySeries.title in Chart.Body.CategorySeries and add new order amount
					currentPvs.setValue(currentPvs.getValue().add(new BigDecimal(amount)));
					ProductShare.getInstance().getProductShare().setPieChartOrLineChart(pie);
					newProduct = false;
				}
			}
			if(newProduct) {
				//create new CategorySeries and Update pieChart Object of ProductShare Instance
				pie.getPieValueSeries().add(pvs);
				ProductShare.getInstance().getProductShare().setPieChartOrLineChart(pie);
			}
			
			//Update Data time frame
	    	getInstance().getProductShare().setDataPeriodEnd(getXMLGregTimestamp());
		}

		/**
		 * Creates a XMLGregorian timestamp
		 * @return XMLGregorian object with the current time and date.
		 */
		private static XMLGregorianCalendar getXMLGregTimestamp() {
			//Update DataTimeFrame in ProductShare chart instance
	    	GregorianCalendar gregCal = new GregorianCalendar();
	    	gregCal.setTime(new Date(System.currentTimeMillis()));
	    	XMLGregorianCalendar xmlGregCal = null;
	    	try {
				xmlGregCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregCal);
			} catch (DatatypeConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return xmlGregCal;
		}

		public KeyIndicator getProductShare() {
			return productShare;
		}
	}
		
